import React, { useEffect, useMemo, useState } from 'react';
import { Drawer, Dropdown, Menu, Tree } from 'antd';
import { EllipsisOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import styles from '../index.less';
import ConfigForm from '@/pages/Design/AppDesign/ConfigForm';


const boxConfig = {
  rowCount: 3,
  rows: [
    {
      key: '1', type: 'row', boxStyle: { width: 100, height: 35 }, children: [
        {
          key: '1-1', type: 'col', boxStyle: { width: 63, height: 100 },
        },
        {
          key: '1-2', type: 'col', boxStyle: { width: 37, height: 100 }, children: [
            { key: '1-2-1', type: 'row', boxStyle: { width: 100, height: 50 } },
            { key: '1-2-2', type: 'row', boxStyle: { width: 100, height: 50 } },
          ],
        },
      ],
    },
    {
      key: '2', type: 'row', boxStyle: { width: 100, height: 35 }, children: [
        { key: '2-1', type: 'col', boxStyle: { width: 50, height: 100 } },
        { key: '2-2', type: 'col', boxStyle: { width: 50, height: 100 } },
      ],
    },
    {
      key: '3', type: 'row', boxStyle: { width: 100, height: 35 }, children: [
        { key: '3-1', type: 'col', boxStyle: { width: 50, height: 100 } },
        { key: '3-2', type: 'col', boxStyle: { width: 50, height: 100 } },
      ],
    },
  ],
};
const AppDesign: React.FC<any> = () => {
  const [container, setContainer] = useState<any>(null);
  const [rows, setRows] = useState<any[]>([]);
  const [trees, setTrees] = useState<any[]>([]);
  const [selectKeys, setSelectKeys] = useState<any[]>();
  const [selectNode, setSelectNode] = useState<any>();
  const [modalVisible, setModalVisible] = useState<boolean>(false);
  const [configFormRender, setConfigFormRender] = useState<any>(<ConfigForm />);
  const appClassName = classNames({
    [styles.appStyle]: true,
    [styles.appSize1]: true,
  });
  useEffect(() => {
    setTreeDatas();
  }, [container]);
  useEffect(() => {
    changeStyle(trees);
  }, [trees]);

  const setTreeDatas = () => {
    const menuClicks = [
      { key: 0, name: '样式配置' },
    ];
    const loop = (rowList: any[]) => {
      if (!rowList || rowList.length === 0) {
        return [];
      }
      rowList = rowList.map((row) => {
        const obj = { ...row };
        const { children, key, boxStyle } = obj;
        const title = (
          <span>
              <b>{key}</b>
               <Dropdown
                 overlay={
                   <Menu onClick={() => {
                     handleModalVisible();
                     setConfigFormRender(<ConfigForm data={boxStyle} onChange={(v) => {
                       setTrees(setTreeData(trees, [key], { boxStyle: { ...boxStyle, ...v } }));
                     }
                     } />);
                   }}>
                     {menuClicks.map((v: any) => {
                       return (
                         <Menu.Item key={v.key}>
                           {v.name}
                         </Menu.Item>
                       );
                     })}
                   </Menu>
                 }
               >
             <EllipsisOutlined style={{ marginLeft: '30px' }} />
            </Dropdown>
            </span>
        );
        return { ...obj, children: loop(children), title };
      });
      return rowList;
    };
    const list: any[] = [];
    boxConfig.rows.forEach(v => {
      list.push({ ...v });
    });
    setTrees(loop(list));
  };
  const changeStyle = (datas: any[]) => {
    if (!container) {
      return;
    }
    const { clientWidth } = container;
    /**
     * 递归按照比例设置宽高
     * @param rowList
     * @param pWidth 标准宽
     * @param pHeight 标准高
     */
    const loop = (rowList: any[], pWidth: number, pHeight: number) => {
      if (!rowList || rowList.length === 0) {
        return [];
      }
      rowList = rowList.map((row) => {
        const obj = { ...row };
        const { boxStyle, children, type, selected } = obj;
        const width: number = boxStyle && boxStyle.width ? pWidth * boxStyle.width / 100 : pWidth;
        const height: number = boxStyle && boxStyle.height ? pHeight * boxStyle.height / 100 : pWidth / 2;
        obj.boxStyle = {
          // background: '#ddd',
          borderRight: type === 'col' ? '1px solid #ddd' : 'none',
          borderBottom: '1px solid #ddd',
          width: `${width}px`,
          height: `${height}px`,
        };
        if (selected) {
          obj.boxStyle.boxShadow = '0px 2px 10px 0px rgba(0,0,0,0.35)';
        }
        obj.children = loop(children, width, height);
        return obj;
      });
      return rowList;
    };
    setRows(loop(datas, clientWidth, clientWidth));
  };
  const boxTrees = useMemo(() => {
    const rowTrees = (rowList: any[]) => {
      const render = rowList.map((row) => {
        let { key, type, boxStyle, children } = row;
        const { height } = boxStyle;
        if (type === 'row') {
          boxStyle = { ...boxStyle, display: 'flex' };
        }
        const rowRender = (
          <div key={key} style={{ width: '100%', height }} onClick={() => {
            onSelect([key], { node: row });
          }}>
            <div style={boxStyle}>
              {rowTrees(children)}
            </div>
          </div>
        );
        return rowRender;
      });
      return render;
    };

    return rowTrees(rows);
  }, [rows]);


  const onDragEnter = (info: any) => {
    // expandedKeys 需要受控时设置
    // this.setState({
    //   expandedKeys: info.expandedKeys,
    // });
  };
  const onDrop = (info: any) => {
    const dropKey = info.node.props.eventKey;
    const dragKey = info.dragNode.props.eventKey;
    const dropPos = info.node.props.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    const loop = (data: any[], key: any, callback: any) => {
      for (let i = 0; i < data.length; i += 1) {
        if (data[i].key === key) {
          return callback(data[i], i, data);
        }
        if (data[i].children) {
          loop(data[i].children, key, callback);
        }
      }
    };
    const data = [...trees];
    // Find dragObject
    let dragObj: any;
    loop(data, dragKey, (item: any, index: any, arr: any[]) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      // Drop on the content
      loop(data, dropKey, (item: any) => {
        item.children = item.children || [];
        // where to insert 示例添加到头部，可以是随意位置
        item.children.unshift(dragObj);
      });
    } else if (
      (info.node.props.children || []).length > 0 && // Has children
      info.node.props.expanded && // Is expanded
      dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, (item: any) => {
        item.children = item.children || [];
        // where to insert 示例添加到头部，可以是随意位置
        item.children.unshift(dragObj);
        // in previous version, we use item.children.push(dragObj) to insert the
        // item to the tail of the children
      });
    } else {
      let ar: any;
      let i: any;
      loop(data, dropKey, (item: any, index: any, arr: any) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar && ar.splice(i, 0, dragObj);
      } else {
        ar && ar.splice(i + 1, 0, dragObj);
      }
    }
    setTrees(data);
  };
  const selectTreeDataOne = (datas: any[], keys: any[]) => {
    const loop = (list: any[]) => {
      list = list.map((v: any) => {
        if (keys.includes(String(v.key))) {
          v = { ...v, selected: true };
        } else {
          v = { ...v, selected: false };
        }
        v.children = loop(v.children);
        return v;
      });
      return list;
    };
    return loop(datas);
  };
  const setTreeData = (datas: any[], keys: any[], pararm: any) => {
    const loop = (list: any[]) => {
      list = list.map((v: any) => {
        if (keys.includes(String(v.key))) {
          v = { ...v, ...pararm };
        }
        v.children = loop(v.children);
        return v;
      });
      return list;
    };
    return loop(datas);
  };
  const onSelect = (selectedKeys: any[], e: any) => {
    setSelectKeys(selectedKeys);
    setSelectNode(e.node);
    setTrees(selectTreeDataOne(trees, selectedKeys));
  };
  const handleModalVisible = () => {
    setModalVisible(!modalVisible);
  };
  return (
    <div className={styles.appDesign}>
      <div className={styles.leftBox}>
        <div className={appClassName} id='appDesignBox' ref={(e: any) => {
          setContainer(e);
        }}>
          {[boxTrees]}
        </div>
      </div>
      <Drawer
        title={selectNode && selectNode.key}
        placement='right'
        closable={false}
        onClose={handleModalVisible}
        visible={modalVisible}
        key='right'
      >
        {configFormRender}
      </Drawer>
      <div className={styles.rightBox}>
        <Tree
          className='draggable-tree'
          defaultExpandedKeys={['0']}
          selectedKeys={selectKeys}
          draggable
          blockNode
          onDragEnter={onDragEnter}
          onDrop={onDrop}
          treeData={[{ key: '0', title: '布局设计', children: trees }]}
          onSelect={onSelect}
        />
      </div>
    </div>
  );
};
export default AppDesign;
